/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package assisisw.smartcal.persistencesubsystem;

import assisisw.smartcal.entitysubsystem.Calendar;
import assisisw.smartcal.entitysubsystem.User;
import assisisw.smartcal.utilities.Configuration;
import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

/**
 *
 * @author Francesco
 */
@Stateless ()
public class PostgreSQLJPACalendarDAO implements ICalendarDAO
{
 
    // Static Fields
    
    /***/
    private static final String FIND_ALL_QUERY_STRING = "SELECT c FROM Calendar AS c" ;
    
    /***/
    private static final String FIND_BY_ID_QUERY_STRING = "SELECT c FROM Calendar AS c WHERE c.id = :id" ;
    
    /***/
    private static final String FIND_BY_USER_QUERY_STRING = "SELECT c FROM Calendar AS c WHERE c.owner = :owner" ;
    
    /***/
    private static final String UPDATE_BY_ID_QUERY_STRING = "UPDATE c FROM Calendar AS c SET c.name = :name WHERE c.id = :id" ;
    
    /***/
    private static final String REMOVE_BY_ID_QUERY_STRING = "DELETE FROM Calendar AS c WHERE c.id = :id" ;
    
    // Instance Fields
    
    /***/
    private Query findAllQuery ;
    
    /***/
    private TypedQuery < Calendar > findByIdQuery ;  
    
    /***/
    private Query findByUserQuery ;
    
    /***/
    private Query updateByIdQuery ;
    
    /***/
    private Query deleteByIdQuery ;
    
    /***/
    @PersistenceContext ( unitName = Configuration.PU_NAME , type = PersistenceContextType.TRANSACTION )
    private EntityManager entityManager ;
    
    // Instance Methods
    
    /***/
    public PostgreSQLJPACalendarDAO () {}
    
    /***/
    @PostConstruct
    public void init () 
    {
        findAllQuery = entityManager.createQuery ( FIND_ALL_QUERY_STRING ) ;
        findByIdQuery = entityManager.createQuery ( FIND_BY_ID_QUERY_STRING , Calendar.class ) ;
        findByUserQuery = entityManager.createQuery ( FIND_BY_USER_QUERY_STRING ) ;
        //updateByIdQuery = entityManager.createQuery ( UPDATE_BY_ID_QUERY_STRING ) ;
        deleteByIdQuery = entityManager.createQuery ( REMOVE_BY_ID_QUERY_STRING ) ;
    }
    
    @Override
    public Calendar findById ( int id ) 
    {
        Calendar res ;
        res = entityManager.find ( Calendar.class , id ) ;
        return res ;
    }
    
    /***/
    public Iterable < Calendar > findAll () 
    {
        Iterable < Calendar > res ;
        res = findAllQuery.getResultList () ;
        return res ;
    }
    
    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public Iterable < Calendar > findByUser ( User user ) 
    {
        Iterable < Calendar > result ;
        if ( user != null )
        {
            findByUserQuery.setParameter ( "owner" , user ) ;
            result = findByUserQuery.getResultList () ;
        }
        else
            throw new IllegalArgumentException () ;
        return result ;
    }

    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public void insert ( Calendar calendar ) 
    {
        if ( calendar != null )
        {
            entityManager.persist ( calendar ) ;
            entityManager.flush();
        }
        else
            throw new IllegalArgumentException () ;
    }
 
    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public void update ( Calendar calendar ) 
    {
        int result ;
        if ( calendar != null )
        {
            //updateByIdQuery.
                    //setParameter ( "name" , calendar.getName() ).
                    //setParameter ( "id" , calendar.getId() ).
                    //executeUpdate();
            entityManager.merge ( calendar ) ;
            entityManager.flush();
        }
        else
            throw new IllegalArgumentException () ;
    }

    /**
     * AS THE SUPER'S ONE.
     */
    @Override
    public void delete ( Calendar calendar ) 
    {
        int res ;
        if ( calendar != null )
        {
            //entityManager.merge(calendar);
            //entityManager.remove ( calendar ) ;
            res = deleteByIdQuery.
                    setParameter("id", calendar.getId() ).
                    executeUpdate();
            entityManager.flush();
        }
        else
            throw new IllegalArgumentException () ;
    }
    
}
